Skip to content

Sync with the stable documentation branch #17014

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 2 commits into from
Feb 27, 2023
Merged

Conversation

github-actions[bot]
Copy link
Contributor

This pull request is syncing the main with changes from language-reference-stable.

It was created automatically after a46d730 by @Kordyjan

mgyucht and others added 2 commits February 26, 2023 12:39
The example of how using clauses are expanded by the compiler is not correct. `descending` accepts a context parameter for an ordering of the elements of the list, not an ordering of the list itself. I just tested this out in the repl:

```scala
scala> trait Ord[T]:
     |   def compare(x: T, y: T): Int
     |   extension (x: T)
     |     def < (y: T) = compare(x, y) < 0
     |     def > (y: T) = compare(x, y) > 0
     |
// defined trait Ord

scala> def max[T](x: T, y: T)(using ord: Ord[T]): T =
     |   if ord.compare(x, y) < 0 then y else x
     |
def max[T](x: T, y: T)(using ord: Ord[T]): T

scala> def maximum[T](xs: List[T])(using Ord[T]): T =
     |   xs.reduceLeft(max)
     |
def maximum[T](xs: List[T])(using x$2: Ord[T]): T

scala> given intOrd: Ord[Int] with
     |   def compare(x: Int, y: Int) =
     |     if x < y then -1 else if x > y then +1 else 0
     |
     | given listOrd[T](using ord: Ord[T]): Ord[List[T]] with
     |
     |   def compare(xs: List[T], ys: List[T]): Int = (xs, ys) match
     |     case (Nil, Nil) => 0
     |     case (Nil, _) => -1
     |     case (_, Nil) => +1
     |     case (x :: xs1, y :: ys1) =>
     |       val fst = ord.compare(x, y)
     |       if fst != 0 then fst else compare(xs1, ys1)
     |
// defined object intOrd
// defined class listOrd
def listOrd[T](using ord: Ord[T]): listOrd[T]

scala> val xs = List(1, 10, 2, 9, 3, 8, 4, 7, 5, 6)
val xs: List[Int] = List(1, 10, 2, 9, 3, 8, 4, 7, 5, 6)

scala> maximum(xs)
val res0: Int = 10

scala> def descending[T](using asc: Ord[T]): Ord[T] = new Ord[T]:
     |   def compare(x: T, y: T) = asc.compare(y, x)
     |
     | def minimum[T](xs: List[T])(using Ord[T]) =
     |   maximum(xs)(using descending)
     |
def descending[T](using asc: Ord[T]): Ord[T]
def minimum[T](xs: List[T])(using x$2: Ord[T]): T

scala> maximum(xs)(using descending)
val res1: Int = 1

scala> maximum(xs)(using descending(using intOrd))
val res2: Int = 1

scala> maximum(xs)(using descending(using listOrd))
-- [E007] Type Mismatch Error: -------------------------------------------------
1 |maximum(xs)(using descending(using listOrd))
  |                                   ^^^^^^^
  |                                   Found:    listOrd[Int]
  |                                   Required: Ord[Int]
  |
  | longer explanation available when compiling with `-explain`
1 error found
```
)

The example of how using clauses are expanded by the compiler is not
correct. `descending` accepts a context parameter for an ordering of the
elements of the list, not an ordering of lists. I just tested this out
in the repl:

```scala
scala> trait Ord[T]:
     |   def compare(x: T, y: T): Int
     |   extension (x: T)
     |     def < (y: T) = compare(x, y) < 0
     |     def > (y: T) = compare(x, y) > 0
     |
// defined trait Ord

scala> def max[T](x: T, y: T)(using ord: Ord[T]): T =
     |   if ord.compare(x, y) < 0 then y else x
     |
def max[T](x: T, y: T)(using ord: Ord[T]): T

scala> def maximum[T](xs: List[T])(using Ord[T]): T =
     |   xs.reduceLeft(max)
     |
def maximum[T](xs: List[T])(using x$2: Ord[T]): T

scala> given intOrd: Ord[Int] with
     |   def compare(x: Int, y: Int) =
     |     if x < y then -1 else if x > y then +1 else 0
     |
     | given listOrd[T](using ord: Ord[T]): Ord[List[T]] with
     |
     |   def compare(xs: List[T], ys: List[T]): Int = (xs, ys) match
     |     case (Nil, Nil) => 0
     |     case (Nil, _) => -1
     |     case (_, Nil) => +1
     |     case (x :: xs1, y :: ys1) =>
     |       val fst = ord.compare(x, y)
     |       if fst != 0 then fst else compare(xs1, ys1)
     |
// defined object intOrd
// defined class listOrd
def listOrd[T](using ord: Ord[T]): listOrd[T]

scala> val xs = List(1, 10, 2, 9, 3, 8, 4, 7, 5, 6)
val xs: List[Int] = List(1, 10, 2, 9, 3, 8, 4, 7, 5, 6)

scala> maximum(xs)
val res0: Int = 10

scala> def descending[T](using asc: Ord[T]): Ord[T] = new Ord[T]:
     |   def compare(x: T, y: T) = asc.compare(y, x)
     |
     | def minimum[T](xs: List[T])(using Ord[T]) =
     |   maximum(xs)(using descending)
     |
def descending[T](using asc: Ord[T]): Ord[T]
def minimum[T](xs: List[T])(using x$2: Ord[T]): T

scala> maximum(xs)(using descending)
val res1: Int = 1

scala> maximum(xs)(using descending(using intOrd))
val res2: Int = 1

scala> maximum(xs)(using descending(using listOrd))
-- [E007] Type Mismatch Error: -------------------------------------------------
1 |maximum(xs)(using descending(using listOrd))
  |                                   ^^^^^^^
  |                                   Found:    listOrd[Int]
  |                                   Required: Ord[Int]
  |
  | longer explanation available when compiling with `-explain`
1 error found
```

I have just signed the CLA.
@Kordyjan Kordyjan merged commit b09af10 into main Feb 27, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants